iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
2

我這次標題直接給她猛烈的亂下,但其實Mixins就真的是代表一個 讓元件共用的方法,Mixin 就是指這個共用的元件,而這個元件可以包含任何的component option~ (option = data, methods, computed...)

前言

我們之所以會需要這個東西是各位可以想像一下,如果今天有一些methods,或是computed會常常需要用到,舉個例子,今天我們一個網頁裡面有很多地方都要做一個user 驗證的事情,那我們就要在每個Vue file裡面的methods做一樣的事情。

但是,老話一句~ 我懶XD,大家也懶所以就有了這個樣子的東西,我們可以在一個地方寫好東西,之後直接引進來!

不說了我們就直接進code。首先我們先define一個 mixin object:

var firstMixin = {
  created: function () {
    this.gretting()
  },
  methods: {
    greeting: function () {
      console.log('hello I am Mixin')
    }
  }
}

所以我們定義了一個mixin object叫做 firstMixin,我們綁定的component option 就是 methods本人~

接下來要怎麼應用他呢? 我們進到component裡面 (這邊用最簡單的new Vue({}))

new Vue({
  mixins: [mixin],
});

這樣就可以成功呼叫囉!


應用到project上~

各位可以打開project了~ 不知道各位做的怎麼樣,進度到哪
我們之前應該有一個東西,在Home.vue裡面~ 我已經把他額外做出來放在一個新的vue檔案裡面。

<template>
  <div>
    <b-card
      v-for="blog in this.blogs"
      :key="blog.id"
      :title="blog.title"
      img-src="https://picsum.photos/600/300/?image=25"
      img-alt="Image"
      img-top
      tag="article"
      style="max-width: 20rem;"
      class="mb-2"
    >
      <b-card-text>
        {{ blog.body }}
      </b-card-text>

      <b-button href="#" variant="primary">See More</b-button>
    </b-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      blogs: [],
    };
  },
  created() {
    this.$http
      .get("http://jsonplaceholder.typicode.com/posts")
      .then(function(data) {
        this.blogs = data.body.slice(0, 10);
      });
  },
};
</script>

現在我們希望要做到的就是一個可以搜尋 filter這些blogs的功能,就是可以在一個文字框裡面搜尋一些字,然後系統可以透過這個函示幫忙尋找那些文章含有這些關鍵字!


先創一個mixins

我們先在src裡面創一個資料夾叫做mixins,然後在裡面創一個JavaScript 檔案,大概這個位置:
https://ithelp.ithome.com.tw/upload/images/20200917/20129730CQgFMuhBWY.jpg

好了之後進到 searchMixin.js這個檔案裏面,然後打上這串:

export default {
    computed: {
        filteredBlogs: function() {
            return this.blogs.filter((blog) => {
                return blog.title.match(this.search);
            });
        }
    }
};

這邊一樣注意幾個點~

  • export: 我們要在這邊輸出這個mixin,讓其他人可以在不同的component裡面輸入~
  • computed: 這就是屬於component 裡面的options之一
  • this: 這邊有一個this,但是如果有印象的話,this 通常都要綁定data(){}裡面的資料,但是這邊沒有data啊? 這邊的this是要看被哪一個component引入*(import)*的。
  • filter()=>{} 這也會回傳出一個新的陣列,這劇的意思就是我把原本的陣列this.blogs放進去,然後他要 filter出有沒有符合 this.search的文章,把有的都放進新的陣列!

Import進去component

那既然我們已經寫好mixin,他也已經準備隨時都可以export了,我們就在已經寫好的code裡面import她吧!

<script>
import searchMixin from '../mixins/searchMixin';
export default {
  data() {
    return {
      blogs: [],
      search: '',
    };
  },
  created() {
    this.$http
      .get("http://jsonplaceholder.typicode.com/posts")
      .then(function(data) {
        this.blogs = data.body.slice(0, 10);
      });
  },
  mixins: [searchMixin]
};
</script>

在來看幾個重點:

  • 我們在一開始的地方有 import這個mixin所在的位置
  • 我們在datacreated同一層放了mixin,因為如果還記得的話,我們的mixin object是一個computed()
  • 我多增加了一個data叫做search,那是要拿來記錄user input要查的資料

DOM上取用新陣列filteredBlogs

那我們都已經引進了mixin,剛剛也說到filter出來的新陣列就會儲存在 filteredBlogs裡面,所以我們這邊就可以直接使用新的陣列來跑v-for了~

<template>
  <div>
    <input type="text" v-model="search" placeholder="search blogs" />
    <b-card
      v-for="blog in filteredBlogs"
      :key="blog.id"
      :title="blog.title"
      img-src="https://picsum.photos/600/300/?image=25"
      img-alt="Image"
      img-top
      tag="article"
      style="max-width: 20rem;"
      class="mb-2"
    >
      <b-card-text>
        {{ blog.body }}
      </b-card-text>

      <b-button href="#" variant="primary">See More</b-button>
    </b-card>
  </div>
</template>
  • 多了一個input來拿取user想要查詢filter的資料 -> 丟到this.search這個data裡面。
  • 我們讓原本的this.blogs改成filteredBlogs,在一開始沒有filter的時候他就是 = this.blogs,但有filter之後他就會回傳新的陣列讓我們列出來~

    這樣就大功告成啦~其實相當簡單的一個概念,filter就是讓程式去篩選要跟不要的,然後得出一個新的陣列之後再把它v-for列出來!

後記

今天最主要就是介紹這個好用的mixin~ 的確是vue可以接受的共用功能 (不要抨擊我亂下標題XD),明天會傳coding,少一點觀念
.
.
.
可能吧
/images/emoticon/emoticon01.gif


上一篇
【D16 - 用Vue實作網頁】等等!!我還對JacaScript不熟www
下一篇
【D18 - 用Vue實作網頁】做出一個美美的部落格
系列文
到底要怎麼開始開發網站? --- 從入門到使用Vue, Firebase製作老闆交代的網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言